#pragma once
#include <unistd.h>
#include <functional>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "socket.hpp"

// void *IgnChild(void *argv)
// {
//     while (true)
//     {
//         int rid = waitpid(-1, nullptr, WNOHANG);
//         if(rid <= 0)
//             break;
//     }
// }

using func_t = std::function<std::string(std::string& package)>;

class TcpServer
{
public:
    TcpServer(uint16_t port, std::string ip, func_t callback)
        : _port(port), _ip(ip), _callback(callback)
    {
    }
    ~TcpServer()
    {
    }

    void Init()
    {
        _listensock.Socket();
        _listensock.Bind(_port, _ip);
        _listensock.Listen();
    }

    void Start()
    {
        signal(SIGCHLD, SIG_IGN);
        while (true)
        {
            uint16_t clientport;
            std::string clientip;
            int sockfd = _listensock.Accept(clientport, clientip);
            if (sockfd < 0)
                continue;

            if(fork() == 0)
            {
                std::cout << "fork success" << std::endl;
                _listensock.Close();
                // 计算
                char buffer[1024];
                std::string in_buffer;
                while (true)
                {
                    ssize_t n = read(sockfd, buffer, sizeof(buffer)-1);
                    if(n > 0)
                    {
                        buffer[n] = 0;
                        in_buffer += buffer;

                        while(true)
                        {
                            sleep(1);
                            std::string info = _callback(in_buffer);
                            
                            if(info.empty()) break;
                            
                            write(sockfd, info.c_str(), info.size());
                        }
                    }
                }
                exit(0);
            }
        }
    }

private:
    uint16_t _port;
    std::string _ip;
    Sock _listensock;
    func_t _callback;
};